use regex::Regex;

enum Rule {
    // 人员类型
    Man(u32, u32),  // 出生年月
    Woman(u32, u32, u32) // 出生年月，原法定退休年龄
}

fn duration_months(year1: u32, month1: u32, year2: u32, month2: u32) -> i32 {
    // 月份差
    (year2 as i32 - year1 as i32) * 12 + (month2 as i32 - month1 as i32)
}

fn add_months_to_date(year: u32, month: u32, months: i32) -> (u32, u32) {
    // 加上月份数，返回新的年月
    let mut year_sum = year as i32 + months / 12;
    let mut month_sum = month as i32 + months % 12;
    if month_sum > 12 {
        year_sum += 1;
        month_sum -= 12;
    }
    (year_sum as u32, month_sum as u32)
}

fn get_new_retire_info(rule: &Rule) -> String {
    let format_float_number = |num: f64| -> String {
        if num.fract() == 0.0 {
            format!("{:.0}", num)
        } else {
            format!("{:.2}", num)
        }
    };
    match rule {
        Rule::Man(year, month) => {
            let mut duration = duration_months(1965, 1, *year, *month);
            if duration < 0 {
                duration = -4;
            } else if duration > 11 * 12 + 11 {
                duration = 11 * 12 + 11;
            }
            let delay_months = duration / 4 + 1;
            let new_retire_date = add_months_to_date(*year, *month, delay_months + 60 * 12);
            let retire_age = 60 as f64 + delay_months as f64 / 12.0;
            format!("{}-{:0>2},{},{}", new_retire_date.0, new_retire_date.1, format_float_number(retire_age), delay_months)
        }   
        Rule::Woman(year, month, origin_retire_age) => {
            if *origin_retire_age == 50 {
                let mut duration = duration_months(1975, 1, *year, *month);
                if duration < 0 {
                    duration = -2;
                } else if duration > 9 * 12 + 11 {
                    duration = 9 * 12 + 11;
                }
                let delay_months = duration / 2 + 1;
                let new_retire_date = add_months_to_date(*year, *month, delay_months + 50 * 12);
                let retire_age = 50 as f64 + delay_months as f64 / 12.0;
                format!("{}-{:0>2},{},{}", new_retire_date.0, new_retire_date.1, format_float_number(retire_age), delay_months)
            } else if *origin_retire_age == 55 {
                let mut duration = duration_months(1970, 1, *year, *month);
                if duration < 0 {
                    duration = -4;
                } else if duration > 11 * 12 + 11 {
                    duration = 11 * 12 + 11;
                }
                let delay_months = duration / 4 + 1;
                let new_retire_date = add_months_to_date(*year, *month, delay_months + 55 * 12);
                let retire_age = 55 as f64 + delay_months as f64 / 12.0;
                format!("{}-{:0>2},{},{}", new_retire_date.0, new_retire_date.1, format_float_number(retire_age), delay_months)
            } else {
                unreachable!()
            }
        }
    }
}

pub fn retire_time(time: &str, tp: &str) -> String {
    let time_regex = Regex::new(r"^(\d{4})-(\d{2})$").unwrap();
    let man_regex = Regex::new(r"^男职工$").unwrap();
    let woman_regex = Regex::new(r"^原法定退休年龄(50|55)周岁女职工$").unwrap();
    let mut ret = String::new();
    if let Some(cap) = time_regex.captures(time) {
        let year = cap[1].parse::<u32>().unwrap();
        let month = cap[2].parse::<u32>().unwrap();
        if let Some(_) = man_regex.captures(tp) {
            ret = get_new_retire_info(&Rule::Man(year, month));        
        } else if let Some(cap) = woman_regex.captures(tp) {
            let origin_retire_age = cap[1].parse::<u32>().unwrap();
            ret = get_new_retire_info(&Rule::Woman(year, month, origin_retire_age));        
        }
    }
    ret
}
